﻿using Sgr.Domain.Repositories;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Sgr.UPMS.Domain.Users
{
    /// <summary>
    /// 用户仓储接口
    /// </summary>
    /// <remarks>
    /// 提供用户相关的数据访问操作：
    /// - 用户基础CRUD操作（继承自IBaseRepository）
    /// - 用户关系查询（部门、职务、角色等）
    /// - 用户名称唯一性检查
    /// </remarks>
    public interface IUserRepository : IBaseRepositoryOfTEntityAndTPrimaryKey<User, long>
    {
        #region 用户查询

        /// <summary>
        /// 根据登录名获取用户
        /// </summary>
        /// <param name="loginName">登录名</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户实体，不存在返回null</returns>
        Task<User?> GetByLoginNameAsync(
            string loginName,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据登录名获取用户（包含导航属性）
        /// </summary>
        /// <param name="loginName">登录名</param>
        /// <param name="propertiesToInclude">要包含的导航属性</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户实体，不存在返回null</returns>
        Task<User?> GetByLoginNameAsync(
            string loginName,
            string[] propertiesToInclude,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据邮箱名称获取用户
        /// </summary>
        /// <param name="email">邮箱</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户实体，不存在返回null</returns>
        Task<User?> GetByEmailAsync(
            string email,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 根据手机号码获取用户
        /// </summary>
        /// <param name="phone">手机号码</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户实体，不存在返回null</returns>
        Task<User?> GetByPhoneAsync(
            string phone,
            CancellationToken cancellationToken = default);

        #endregion 用户查询

        #region 组织架构关系查询

        /// <summary>
        /// 获取指定组织机构下的所有用户
        /// </summary>
        /// <param name="orgId">组织机构ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户列表</returns>
        Task<IEnumerable<User>> GetByOrgIdAsync(
            long orgId,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取指定部门下的所有用户
        /// </summary>
        /// <param name="departmentId">部门ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户列表</returns>
        Task<IEnumerable<User>> GetByDepartmentIdAsync(
            long departmentId,
            CancellationToken cancellationToken = default);

        #endregion 组织架构关系查询

        #region 职务关系查询

        /// <summary>
        /// 获取拥有指定职务的所有用户
        /// </summary>
        /// <param name="dutyId">职务ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户列表</returns>
        Task<IEnumerable<User>> GetByDutyIdAsync(
            long dutyId,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取首要职务为指定职务的所有用户
        /// </summary>
        /// <param name="primaryDutyId">首要职务ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户列表</returns>
        Task<IEnumerable<User>> GetByPrimaryDutyIdAsync(
            long primaryDutyId,
            CancellationToken cancellationToken = default);

        #endregion 职务关系查询

        #region 角色关系查询

        /// <summary>
        /// 获取拥有指定角色的所有用户
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户列表</returns>
        Task<IEnumerable<User>> GetByRoleIdAsync(
            long roleId,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取拥有指定角色的所有用户ID和组织ID
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<IEnumerable<(long Id, long OrgId)>> GetUserIdAndOrgIdByRoleIdAsync(
            long roleId,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查角色是否被用户使用
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>true: 角色被使用; false: 角色未被使用</returns>
        Task<bool> HasUserUseRoleAsync(
            long roleId,
            CancellationToken cancellationToken = default);

        #endregion 角色关系查询

        #region 唯一性检查

        /// <summary>
        /// 检查登录名是否唯一
        /// </summary>
        /// <param name="name">登录名</param>
        /// <param name="excludedId">需要排除的用户ID（用于编辑场景）</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>true: 登录名唯一; false: 登录名已存在</returns>
        Task<bool> LoginNameIsUniqueAsync(
            string name,
            long? excludedId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查手机号码是否唯一
        /// </summary>
        /// <param name="phoneNumber"></param>
        /// <param name="excludedId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> PhoneNumberIsUniqueAsync(
            string phoneNumber,
            long? excludedId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查手机号码是否唯一
        /// </summary>
        /// <param name="email"></param>
        /// <param name="excludedId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> EmailIsUniqueAsync(
            string email,
            long? excludedId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查微信openId是否唯一
        /// </summary>
        /// <param name="weChatOpenId"></param>
        /// <param name="excludedId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> WeChatOpenIdIsUniqueAsync(
            string weChatOpenId,
            long? excludedId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 检查微信unionId是否唯一
        /// </summary>
        /// <param name="weChatUnionId"></param>
        /// <param name="excludedId"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> WeChatUnionIdIsUniqueAsync(
            string weChatUnionId,
            long? excludedId = null,
            CancellationToken cancellationToken = default);

        #endregion 唯一性检查
    }
}